package com.njlime.cms.service.sys;

import com.alibaba.fastjson.JSONObject;
import com.njlime.cms.entities.WxMenu;
import com.njlime.cms.repository.sys.WxMenuDao;
import com.njlime.core.exception.BusinessException;
import com.njlime.core.exception.ExceptionState;
import com.njlime.core.helper.GlobalValue;
import com.njlime.core.sdk.wechat.WeChatUtil;
import com.njlime.core.sdk.wechat.jsapi.AccessToken;
import com.njlime.core.sdk.wechat.menu.LevelMenu;
import com.njlime.core.sdk.wechat.menu.Menu;
import com.njlime.core.sdk.wechat.menu.MenuButton;
import com.njlime.core.sdk.wechat.menu.SubMenuButton;
import com.njlime.core.utils.StringUtil;
import com.njlime.sys.entities.UnitWxConfig;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by Dean on 2017-10-26.
 */
@Service
@Transactional(readOnly = true)
public class WxMenuService {

    @Resource
    private WxMenuDao wxMenuDao;

    /**
     * 查询
     * @param id
     * @return
     */
    public WxMenu findOne(int id){
        return wxMenuDao.findOne(id);
    }

    /**
     * 数量
     *
     * @param pid
     * @return
     */
    public int wxMenuCount(int pid) {
        return wxMenuDao.getMenuCount(pid);
    }

    /**
     * 列表
     *
     * @param unit_id
     * @return
     */
    public List<Map<String,Object>> wxMenuList(int unit_id) {
        List<WxMenu> menuList = wxMenuDao.wxMenuList(unit_id);
        List<Map<String, Object>> mapList = new ArrayList<>();
        if(menuList != null && menuList.size() > 0){
            for (WxMenu wxMenu : menuList) {
                Map<String, Object> map = new HashMap<>();
                map.put("id", wxMenu.getId());
                map.put("parent_id", wxMenu.getPid());
                map.put("name", wxMenu.getName());
                map.put("url", wxMenu.getUrl());
                map.put("pagepath", wxMenu.getPagepath());
                map.put("type", wxMenu.getType());
                map.put("key", wxMenu.getEkey());
                mapList.add(map);
            }
            mapList =  treeBean(mapList, 0);
        }
        return mapList;
    }

    /**
     * 保存
     * @param wxMenu
     */
    @Transactional(readOnly = false)
    public int saveWxMenu(WxMenu wxMenu) {

        if(wxMenu.getId() != null){
            wxMenuDao.updateWxMenu(wxMenu);
        }else{
            wxMenu.setCreate_time(new Date());
            wxMenu.setIs_del(GlobalValue.NO);
            wxMenu.setSort(getMaxSort(wxMenu.getUnit_id()) + 1);
            wxMenuDao.save(wxMenu);
            if(wxMenu.getPid() != 0){
                WxMenu parent = wxMenuDao.findOne(wxMenu.getPid());
                if(!"menu".equals(parent.getType())){
                    parent.setType("menu");
                    wxMenuDao.updateWxMenu(parent);
                }
            }
        }
        return wxMenu.getId();
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @Transactional(readOnly = false)
    public void delWxMenu(int id) {
        WxMenu wxMenu = wxMenuDao.findOne(id);
        int count = wxMenuCount(wxMenu.getId());
        if(count > 0){
            throw new BusinessException("菜单下有子菜单，不能删除");
        }
        //return wxMenuDao.delWxMenu(id);
        wxMenuDao.delete(id);
        if(wxMenu.getPid() != 0){
            int p_count = wxMenuCount(wxMenu.getPid());
            if(p_count == 0){
                WxMenu pm = new WxMenu();
                pm.setId(wxMenu.getPid());
                pm.setType("0");
                wxMenuDao.updateWxMenu(pm);
            }
        }
    }

    /**
     * 发布
     * @param unit_id
     */
    public int publish(int unit_id, UnitWxConfig unitWxConfig){
        List<Map<String,Object>> menuList = wxMenuList(unit_id);
        if(menuList != null && menuList.size() > 0){
            Menu menu = new Menu();
            menu.setButton(new MenuButton[menuList.size()]);
            for(int i = 0;i<menuList.size();i++){
                Map<String,Object> wxMenu = menuList.get(i);
                try {
                    if (wxMenu.get("name").toString().getBytes("utf-8").length > 16) {
                        throw new BusinessException("[" + wxMenu.get("name").toString() + "]名称太长");
                    }
                }catch (Exception e){
                    throw new BusinessException("[" + wxMenu.get("name").toString() + "]名称太长");
                }
                String level_type = (String)wxMenu.get("type");
                if(!StringUtil.isEmpty(level_type)){
                    if("menu".equals(level_type)){
                        LevelMenu levelMenu = new LevelMenu();
                        levelMenu.setName(wxMenu.get("name").toString());
                        List<Map<String,Object>> childList = (List<Map<String,Object>>)wxMenu.get("children");
                        if(childList!= null && childList.size() > 0){
                            levelMenu.setSub_button(new SubMenuButton[childList.size()]);
                            for(int j = 0;j<childList.size();j++){
                                Map<String,Object> sub = childList.get(j);
                                String menu_type = (String)sub.get("type");
                                String menu_name = sub.get("name").toString();
                                if(!StringUtil.isEmpty(menu_type)){
                                    SubMenuButton subMenuButton = new SubMenuButton();
                                    try {
                                        if (menu_name.getBytes("utf-8").length > 60) {
                                            throw new BusinessException("[" + levelMenu.getName() + "-" + menu_name + "]名称太长");
                                        }
                                    }catch (Exception e){
                                        throw new BusinessException("[" + levelMenu.getName() + "-" + menu_name + "]名称太长");
                                    }
                                    subMenuButton.setName(menu_name);
                                    subMenuButton.setType(menu_type);
                                    if("click".equals(menu_type)){
                                        String key = (String)sub.get("key");
                                        if(StringUtil.isEmpty(key)){
                                            throw new BusinessException("[" + levelMenu.getName() + "-" + menu_name + "]素材错误");
                                        }
                                        subMenuButton.setKey(key);
                                    }else if("view".equals(menu_type)){
                                        String url = (String)sub.get("url");
                                        if(StringUtil.isEmpty(url)){
                                            throw new BusinessException("[" + levelMenu.getName() + "-" + menu_name + "]链接地址不能为空");
                                        }
                                        subMenuButton.setUrl(url);
                                    }else if("miniprogram".equals(menu_type)){
                                        String url = (String)sub.get("url");
                                        if(StringUtil.isEmpty(url)){
                                            throw new BusinessException("[" + levelMenu.getName() + "-" + menu_name + "]备用地址不能为空");
                                        }
                                        subMenuButton.setUrl(url);
                                        String pagepath = (String)sub.get("pagepath");
                                        if(StringUtil.isEmpty(pagepath)){
                                            throw new BusinessException("[" + levelMenu.getName() + "-" + menu_name + "]小程序地址不能为空");
                                        }
                                        subMenuButton.setPagepath(pagepath);
                                    }
                                    levelMenu.getSub_button()[j] = subMenuButton;
                                }else{
                                    throw new BusinessException("[" + levelMenu.getName() + "-" + menu_name + "]菜单类型错误");
                                }
                            }
                        }
                        menu.getButton()[i] = levelMenu;
                    }else{
                        SubMenuButton subMenuButton = new SubMenuButton();
                        subMenuButton.setName(wxMenu.get("name").toString());
                        subMenuButton.setType(level_type);
                        if("click".equals(level_type)){
                            String key = (String)wxMenu.get("key");
                            if(StringUtil.isEmpty(key)){
                                throw new BusinessException("[" + subMenuButton.getName() + "]素材错误");
                            }
                            subMenuButton.setKey(key);
                        }else if("view".equals(level_type)){
                            String url = (String)wxMenu.get("url");
                            if(StringUtil.isEmpty(url)){
                                throw new BusinessException("[" + subMenuButton.getName() + "]链接地址不能为空");
                            }
                            subMenuButton.setUrl(url);
                        }else if("miniprogram".equals(level_type)){
                            String url = (String)wxMenu.get("url");
                            if(StringUtil.isEmpty(url)){
                                throw new BusinessException("[" + subMenuButton.getName() + "]备用地址不能为空");
                            }
                            subMenuButton.setUrl(url);
                            String pagepath = (String)wxMenu.get("pagepath");
                            if(StringUtil.isEmpty(pagepath)){
                                throw new BusinessException("[" + subMenuButton.getName() + "]小程序地址不能为空");
                            }
                            subMenuButton.setPagepath(pagepath);
                        }
                        menu.getButton()[i] = subMenuButton;
                    }
                }else{
                    throw new BusinessException("[" + wxMenu.get("name") + "]类型错误");
                }
            }
            AccessToken accessToken = WeChatUtil.getAccessToken(unitWxConfig.getApp_id(), unitWxConfig.getApp_secret());
            int code = WeChatUtil.createMenu(menu,accessToken.getToken());
            return code;
        }else{
            throw new BusinessException("未找到菜单设置");
        }
    }

    private int getMaxSort(int unit_id){
        return wxMenuDao.getMaxSort(unit_id);
    }

    /**
     * 树结构
     * @param list
     * @param parent_id
     * @return
     */
    private List<Map<String, Object>> treeBean(List<Map<String, Object>> list, int parent_id) {
        List<Map<String, Object>> nodeList = new ArrayList<>();
        for (Map<String, Object> map : list) {
            Integer pid = Integer.parseInt(map.get("parent_id").toString());
            Integer id = Integer.parseInt(map.get("id").toString());
            if (parent_id == pid) {
                List<Map<String, Object>> c_node = treeBean(list, id);
                if (c_node != null && c_node.size() > 0) {
                    map.put("children", c_node);
                }
                nodeList.add(map);
            }
        }
        return nodeList;
    }

}
